'use strict'

process.chdir(__dirname);

const titbit = require('titbit');
const fs = require('fs');
const dbcfg=require('./dbconfig.js')
const pg =require('pg')
const wxkey=require('./wxkey.js')
const {httpcli}=require('gohttp')
const token =require('titbit-token')

try{
    fs.accessSync('./images')
} catch(err){
    fs.mkdirSync('./images')
}

let psql=new pg.Pool(dbcfg)
let cert_path='/usr/local/share'

const app = new titbit({
    //开启调试模式，若有错误会输出错误信息
    debug:true,
    globalLog:true,
    cert:`${cert_path}/api.hiehie.top.pem`,
    key:`${cert_path}/api.hiehie.top.key`
})


//添加路由
app.get('/', async c=>{
    c.send('ok');
})


/*-----------------------content路由------------------------------*/
    //获取内容列表
    app.get('/content',async c=>{
        let ret =await psql.query(`select * from content`)
        //等效于c.res.body=ret.rows
        c.send(ret.rows)
    })

    app.get('/id',async c=>{

    })

    //获取内容
    app.get('/content/:id',async c=>{
        let sqltext = `SELECT*FROM content WHERE id=$1`

        let r =await psql.query(sqltext,[c.param.id])

        if(r.rowCount===0){
            return c.status(404).send('content not find')
        }
        c.send(r.rows[0])
    })

    //删除内容
    app.get('/delete/:id',async c=>{
        let sqltext1=`DELETE FROM content WHERE id=$1`
        let r =await psql.query(sqltext1,[c.param.id])
        if(r.rowCount===0){
            return c.status(404).send('content not find')
        }
        c.send(r.rows[0])

    })

    //创建内容
    app.post("/content",async c=>{
        try{
            let data=JSON.parse(c.body)

            let sqltext=`INSERT INTO `
            +` content(id,add_time,detail,title,update_time) `
                +` VALUES($1,$2,$3,$4,$5)`

            //生成唯一id
            let id=c.helper.makeId()
            let tm =Date.now()

            let r =await psql.query(sqltext,[
                id,tm,data.detail,data.title,tm
            ])

            if(r.rowCount===0){
                return c.status(500).send('failed')
            }

            c.send(id)
            
        }catch(err){
            c.status(400).send('it is not json data')
        }

    })
/*-------------------content路由-END------------------------------*/

//适用于静态资源，*表示任意路径
// app.get('/static/*', async c =>{ })

//:后面的内容是动态变化的
app.get('/image/:name', async c => {
    //c.param是一个对象，其中的key值是路由参数的名称
    let imgname = c.param.name

    await c.helper.pipe(`./images/${imgname}`, c.reply)
})

let tok=new token({
    //token有效期，单位为秒
    expires:45,
    //必须是32位字符
    key:'1q2w3e4r5t6y7u8i9o0pazsxdcfvgbhn',
    //必须是16位字符
    iv:'1q2w3e4r5t6y7u8i'
})

app.get('/mp-login/:code',async c=>{
    let auth_url=`https://api.weixin.qq.com/sns/jscode2session`
    +`?appid=${wxkey.appid}`
    +`&secret=${wxkey.secret}`
    +`&js_code=${c.param.code}`
    +`&grant_type=authorization_code`

    let ret = await httpcli.get(auth_url)
                            .then(res=>{
                                return res.json()
                            })
    c.send(tok.make(ret))
})

app.get('/decrypt/:token',async c=>{
    c.send(tok.verify(c.param.token))
})

app.get('/upload', async c=>{
    //c.reply是响应对象，可写的流，在HTTP/1.1中指向response，在HTTP/2中指向http2stream
    await c.helper.pipe('./upload.html', c.reply);
})


app.post('/upload', async c=>{
    //根据name获取文件对象
    let f = c.getFile('image');

    if(!f){
        return c.status(400).send('image not found');
    }
    //根据传入的原始文件名生成唯一文件名，主要使用f.filename的拓展名
    let fname = c.helper.makeName(f.filename)
    //移动文件到指定位置
    await c.moveFile(f, `./images/${fname}`)

     c.send(fname);

})


//运行在2344端口
app.run(2344);

/*
HTTP消息头  content-type 指定了数据的类型（数据的格式）


Client                             Server
content-type描述的值                根据content-type的值决定如何解析Body数据
和要提交的Body数据格式一致


content-type:
multipart/form-data;boundary=xxx -----------------文件解析
text/*                        ------------文件类型
application/*        -------------------要看具体值，application/json也是文本类型
......          ---------------每种类型如何处理是双方设计好的通信方式
1.;

到web框架这一层面，则如何处理是开发框架设计好的，但通常都要遵循一个原则
允许开发者做自己的处理

在文本框架内：
multipart类型   c.body是object乐行 文件信息解析到c.files中
application/x-www-form-urlencoded 传统的表单类型  c.body是object类型，用于获取提交的表单数据
text/*  c.body  是文本类型  c.body-c.rawBody.toString('utf-8')
其他类型  c.body是buffer类型，就是对c.rawBody的引用



*/